package com.industry.framework.core.generic;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.industry.framework.common.Result;
import com.industry.framework.common.page.TableDataInfo;
import com.industry.framework.core.annountions.monitor.IdooMonitorService;
import com.industry.framework.core.context.CoreApplicationContext;
import com.industry.framework.core.exception.CoreInvalidateArgsException;
import com.industry.framework.core.generic.record.RecordBuilder;
import com.industry.framework.core.generic.record.dataobject.dto.RecordDto;
import com.industry.framework.core.generic.record.dataobject.vo.RecordVo;
import com.industry.framework.core.generic.table.TableConfigInfo;
import com.industry.framework.core.wrapper.QueryTableWrapper;
import com.industry.framework.core.wrapper.RecordSearchWrapper;
import com.industry.framework.core.wrapper.UpdateWrapper;
import com.industry.framework.core.wrapper.WrapperExtractor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;

/**
 * @Author nbZhuozh
 * @Date 2025-03-19  11:17
 **/
@RestController
@RequestMapping("idoo-core")
public abstract class AbstractCoreGenericController<T,ID> implements GenericController<T,ID> {

    private static final Logger log = LoggerFactory.getLogger(AbstractCoreGenericController.class);

    private final Class<T> entityClass;

    public Class<T> getEntityClass() {
        return entityClass;
    }
    @SuppressWarnings("unchecked")
    public AbstractCoreGenericController() {
        Type type = this.getClass().getGenericSuperclass();
        ParameterizedType paramType = (ParameterizedType) type;
        Type[] actualTypeArguments = paramType.getActualTypeArguments();

        this.entityClass = (Class<T>) actualTypeArguments[0];
    }

    @Override
    @GetMapping("/query-details/{id}")
    @IdooMonitorService("详情查询")
    public Result<T> queryDetails(@PathVariable("id") String id) {
        //参数校验
        if(StringUtils.isEmpty(id)){
            log.error("【CoreGenericController [queryDetails] defind servic】");
            throw new CoreInvalidateArgsException("CoreGenericController [queryDetails] defind args id");
        }
        //获取是实体T 对应的业务类 ServiceImpl
        return Result.success((T) getService().getDetails(id));
    }


    @IdooMonitorService("列表查询")
    @PostMapping("/query-table-list")
    public Result<TableDataInfo<T>> queryList(@RequestBody QueryTableWrapper<T> queryTableWrapper) {
        try{
            Class<T> entityClass = getEntityClass(); // 需要确保 getType() 返回 Class<T>
            WrapperExtractor<T> wrapperExtractor = new WrapperExtractor<>(entityClass);
            //构造condition查询
            QueryWrapper<T> wrapper = wrapperExtractor.queryWrapperBuilder(queryTableWrapper);
            //构造Page
            IPage<T> iPage = getService().getMapper().selectPage(wrapperExtractor.excuteRowBounds(), wrapper);
            return Result.success(TableDataInfo.build(iPage));
        } catch (Exception e){
            e.printStackTrace();
            return Result.fail("服务故障");
        }
    }


    @Override
    @IdooMonitorService("查询多功能搜索框配置")
    @GetMapping("/query-table-config")
    public Result<TableConfigInfo> tableListQueryConfiger(){
        return Result.success(getService().tableListQueryConfiger());
    }

    @Override
    @IdooMonitorService("查询全部")
    @GetMapping("/query-all")
    public Result<List<T>> queryAll(){
        return Result.success(getService().queryAll());
    }



    @Override
    @PostMapping("/del-id")
    @IdooMonitorService("删除")
    public Result<Object> delById(@RequestBody String id) {
        //参数校验
        if(StringUtils.isEmpty(id)){
            log.error("【CoreGenericController [delById] defind servic】");
            throw new CoreInvalidateArgsException("CoreGenericController [delById] defind args id");
        }
        Map<String,String> idsMap = new HashMap<>();
        idsMap.put("ids",id);
        delByIds(idsMap);
        return Result.success();
    }

    @Override
    @PostMapping("/del-ids")
    @IdooMonitorService("批量删除")
    public Result<Object> delByIds(@RequestBody Map<String,String> idsMap) {
        if(CollectionUtils.isEmpty(idsMap)){
            return Result.success();
        }
        String ids = idsMap.get("ids");
        //参数校验
        if(StringUtils.isEmpty(ids)){
            log.error("【CoreGenericController [delByIds] defind servic】");
            throw new CoreInvalidateArgsException("CoreGenericController [delByIds] defind args ids");
        }
        getService().delIds(Arrays.asList(ids.split(",")));
        return Result.success();
    }

    @Override
    @PostMapping("/insert")
    @IdooMonitorService("新增")
    public Result<Object> insert(@RequestBody T t) {
        //参数校验
        if(ObjectUtils.isEmpty(t)){
            log.error("【CoreGenericController [insert] defind servic】");
            throw new CoreInvalidateArgsException("CoreGenericController [insert] defind args t");
        }
        Result<Object> objectResult = insertBatch(Collections.singletonList(t));
        return Result.success(objectResult.getData());
    }



    @Override
    @PostMapping("/insertOrUpdate")
    @IdooMonitorService("新增")
    public Result<Object> insertOrUpdate(@RequestBody T t) {
        //参数校验
        if(ObjectUtils.isEmpty(t)){
            log.error("【CoreGenericController [insertOrUpdate] defind servic】");
            throw new CoreInvalidateArgsException("CoreGenericController [insertOrUpdate] defind args t");
        }
        try {
            getService().insertOrUpdate(Collections.singletonList(t));
        }catch (Exception e){
            return Result.fail("insertOrUpdate <ERROR>");
        }
        return Result.success();
    }

    @Override
    @PostMapping("/insert-batch")
    @IdooMonitorService("批量新增")
    public Result<Object> insertBatch(@RequestBody List<T> list) {
        //参数校验
        if(CollectionUtils.isEmpty(list)){
            log.error("【CoreGenericController [insertBatch] defind servic】");
            throw new CoreInvalidateArgsException("CoreGenericController [insertBatch] defind args list");
        }
        List<String> list1 = getService().batchInsert(list);
        return Result.success(list1);
    }

    @Override
    @PostMapping("/modify")
    @IdooMonitorService("修改")
    public Result<Object> update(@RequestBody UpdateWrapper<T> wrapper) {
        //参数校验
        if(ObjectUtils.isEmpty(wrapper)){
            log.error("【CoreGenericController [update] defind servic】");
            throw new CoreInvalidateArgsException("CoreGenericController [update] defind args t");
        }
        getService().batchUpdate(wrapper);
        return Result.success();
    }

    @Override
    @PostMapping("/modify-batch")
    @IdooMonitorService("批量修改")
    public void updateBatch(@RequestBody List<T> list) {
        //参数校验
        if(CollectionUtils.isEmpty(list)){
            log.error("【CoreGenericController [updateBatch] defind servic】");
            throw new CoreInvalidateArgsException("CoreGenericController [update] defind args list");
        }
        getService().batchUpdate(list);
    }

    @Override
    @GetMapping("/query-details-record/{id}")
    @IdooMonitorService("详情操作记录")
    public Result<List<RecordVo>> queryDetailsRecords(@PathVariable("id") String id) {
        if(RecordBuilder.hasTargetOperationRecod(getEntityClass())){
            List<RecordDto> res = getService().queryDetailsRecords(id);
            List<RecordVo> voRes = RecordVo.build(res);
            return Result.success(voRes);
        }
        return Result.fail("当前业务，系统暂未开启操作记录服务。");
    }


    @PostMapping("/insert-remark")
    @IdooMonitorService("新增操作记录备注")
    public Result<Object> insertRecordRemark(@RequestBody Map<String,String> result){
        if (!StringUtils.isEmpty(result.get("remark"))){
            getService().insertRecordRemark(result.get("remark"),result.get("bizId"));
        }
        return Result.success();
    }

    @Override
    @PostMapping("/query-details-record-wrapper")
    @IdooMonitorService("wrapper查询操作记录")
    public Result<List<RecordVo>> queryDetailsRecords(@RequestBody RecordSearchWrapper recordSearchWrapper){
        if(RecordBuilder.hasTargetOperationRecod(getEntityClass())){
            List<RecordDto> res = getService().queryDetailsRecords(recordSearchWrapper);
            List<RecordVo> voRes = RecordVo.build(res);
            return Result.success(voRes);
        }
        return Result.fail("当前业务，系统暂未开启操作记录服务。");
    }

    @Override
    public GenericService getService() {
        if(getEntityClass() == null){
            log.error("【CoreGenericController =========================== [getServiceName] defind servic entity】");
            return null;
        }
        return  CoreApplicationContext.getGenericServiceMap().get(getEntityClass().getSimpleName()+ "Service");
    }

}
